#include "modeencryptbase.h"
#include <QTime>
#include <QDebug>

ModeEncryptBase::ModeEncryptBase(ModeEncryptBase::E_ProgramModeType emProgramModeType,QObject *parent) : QObject(parent)
{
    this->emEncryptModeType = E_EncryptModeType_1;
    this->emProgramModeType = emProgramModeType;
    switch(this->emProgramModeType)
    {
    case E_ProgramModeType_MAIN://加密替换方法
    {
        mapCheckNumber.insert('0','5');
        mapCheckNumber.insert('1','8');
        mapCheckNumber.insert('2','4');
        mapCheckNumber.insert('3','7');
        mapCheckNumber.insert('4','1');
        mapCheckNumber.insert('5','9');
        mapCheckNumber.insert('6','0');
        mapCheckNumber.insert('7','6');
        mapCheckNumber.insert('8','3');
        mapCheckNumber.insert('9','2');

        mapCheckRandNumber.insert(10,'Y');
        mapCheckRandNumber.insert(11,'I');
        mapCheckRandNumber.insert(12,'B');
        mapCheckRandNumber.insert(13,'P');
        mapCheckRandNumber.insert(14,'U');
        mapCheckRandNumber.insert(15,'W');
        mapCheckRandNumber.insert(16,'D');
        mapCheckRandNumber.insert(17,'T');
        mapCheckRandNumber.insert(18,'J');
        mapCheckRandNumber.insert(19,'R');

        //17-33
        mapCheckCharacterAHQLM.insert('A',17);
        mapCheckCharacterAHQLM.insert('H',32);
        mapCheckCharacterAHQLM.insert('Q',24);
        mapCheckCharacterAHQLM.insert('L',30);
        mapCheckCharacterAHQLM.insert('M',29);

        setCheckNumber(mapCheckNumber);
        setCheckRandNumber(mapCheckRandNumber);
        setCheckCharacterAHQLM(mapCheckCharacterAHQLM);
    }
        break;
    default:
    {

    }
        break;
    }
}
QString ModeEncryptBase::encryptLicense(QString strSerialNumber,QString strDate)
{
    QTime time = QTime::currentTime();
    qsrand(time.msec()+time.second()*1000);
    QByteArray ba = strSerialNumber.toLatin1();
    char *Serial = ba.data();
    int s = 0;
    for(int i=0;i<12;i++)
    {
         s += ((int)(Serial[i])-48);
    }

    QByteArray ba2 = strDate.toLatin1();
    char *Date = ba2.data();

    for(int i=0;i<8;i++)
    {
         s += ((int)(Date[i])-48);
    }

    if(emEncryptModeType == E_EncryptModeType_1)
    {
        s+=0;
    }
    else
    {
        s+=111;
    }

    char checksum[4];
    QString s1 = QString::number(s);
    QByteArray ba3 = s1.toLatin1();
    char *s2 = ba3.data();
    int j = 1;
    for(int i = 3;i>=0;i--)
    {
       // if(ba3.count()-j < 0)

        if(ba3.count()-j >= 0)
        {
            checksum[i] = s2[ba3.count()-j];
            j++;
        }
        else
        {
            checksum[i] = '0';
        }
    }
    char p1[12];
    char p2[12];
    p1[0] = checkNumber(Serial[0]);
    for(int i = 1;i<4;i++)
    {
        p1[i] = checkCharacterA(Serial[i]);
    }
    for(int i = 4;i<6;i++)
    {
        p1[i] = checkCharacterH(Serial[i]);
    }
    p1[6] = checkNumber(Serial[6]);
    p1[7] = checkCharacterH(Serial[7]);
    p1[8] = checkNumber(Serial[8]);
    for(int i = 9;i<12;i++)
    {
        p1[i] = checkCharacterQ(Serial[i]);
    }

    for(int i=0;i<2;i++)
    {
        p2[i] = checkCharacterL(Date[i]);
    }
    for(int i=2;i<4;i++)
    {
        p2[i] = checkNumber(Date[i]);
    }
    for(int i=4;i<8;i++)
    {
        p2[i] = checkCharacterM(Date[i]);
    }
    //p2[8] = checkNumber(Date[8]);
    //p2[9] = checkCharacterA(Date[9]);
    for(int i=8;i<10;i++)
    {
        p2[i] = checkCharacterA(checksum[i-8]);
    }
    for(int i=10;i<12;i++)
    {
        p2[i] = checkCharacterQ(checksum[i-8]);
    }
    qDebug()<<p1<<s;
    char p11[19];
    int k = 0;
    int randomNumb;
    for(int i = 0;i < 18;i++)
    {

        if(i == 5 || i == 11 || i == 17)
            p11[i] = '-';
        else if(i == 4 || i == 10 || i == 16)
        {
            //qsrand(time(NULL));
            randomNumb = qrand()%19;
            p11[i] = checkrandNumber(randomNumb);
        }

        else
        {
            p11[i] = p1[k];
            k++;
        }
    }
    p11[18] = '\0';
    char p21[18];
    int m = 0;
    for(int i = 0;i < 17;i++)
    {

        if(i == 5 || i == 11)
            p21[i] = '-';
        else if(i == 4 || i == 10 || i == 16)
        {
            randomNumb = qrand()%19;
            p21[i] = checkrandNumber(randomNumb);
        }
        else
        {
            p21[i] = p2[m];
            m++;
        }
    }
    p21[17] = '\0';
    QString qstr1= QString(QLatin1String(p11));
    QString qstr2= QString(QLatin1String(p21));

    return qstr1+qstr2;
}

char ModeEncryptBase::checkNumber(char n)
{
    QMap<char,char>::iterator iterMap;
    iterMap = mapCheckNumber.find(n);
    if(iterMap != mapCheckNumber.end())
    {
        return iterMap.value();
    }

}

char ModeEncryptBase::checkrandNumber(int n)
{
    QMap<int,char>::iterator iterMap;
    iterMap = mapCheckRandNumber.find(n);
    if(iterMap != mapCheckRandNumber.end())
    {

        return iterMap.value();
    }
    else
    {
        return n+'0';
    }
}

char ModeEncryptBase::checkCharacterA(char c)
{
    QMap<char,int>::iterator iterMap;
    char characterFlag='A';
    iterMap = mapCheckCharacterAHQLM.find(characterFlag);
    if(iterMap != mapCheckCharacterAHQLM.end())
    {
        int valueData =iterMap.value();
        return c+valueData;

    }
    else
    {
        return c+17;
    }

}
char ModeEncryptBase::checkCharacterH(char c)
{
    QMap<char,int>::iterator iterMap;
    char characterFlag='H';
    iterMap = mapCheckCharacterAHQLM.find(characterFlag);
    if(iterMap != mapCheckCharacterAHQLM.end())
    {
        int valueData =iterMap.value();
        return c+valueData;

    }
    else
    {
        return c+32;
    }
}

char ModeEncryptBase::checkCharacterQ(char c)
{
    QMap<char,int>::iterator iterMap;
    char characterFlag='Q';
    iterMap = mapCheckCharacterAHQLM.find(characterFlag);
    if(iterMap != mapCheckCharacterAHQLM.end())
    {
        int valueData =iterMap.value();
        return c+valueData;
    }
    else
    {
        return c+24;
    }
}

char ModeEncryptBase::checkCharacterL(char c)
{
    QMap<char,int>::iterator iterMap;
    char characterFlag='L';
    iterMap = mapCheckCharacterAHQLM.find(characterFlag);
    if(iterMap != mapCheckCharacterAHQLM.end())
    {
        int valueData =iterMap.value();
        return c+valueData;
    }
    else
    {
        return c+30;
    }
}

char ModeEncryptBase::checkCharacterM(char c)
{
    QMap<char,int>::iterator iterMap;
    char characterFlag='M';
    iterMap = mapCheckCharacterAHQLM.find(characterFlag);
    if(iterMap != mapCheckCharacterAHQLM.end())
    {
        int valueData =iterMap.value();
        return c+valueData;
    }
    else
    {
        return c+29;
    }
}

int ModeEncryptBase::setCheckNumber(QMap<char,char>& mapCheckNumber)
{
    QMap<char,char>::iterator iterMap;
    iterMap=mapCheckNumber.begin();
    while(iterMap!=mapCheckNumber.end())
    {
        this->mapCheckNumber.insert(iterMap.key(),iterMap.value());
        iterMap++;
    }
    return 0;
}
int ModeEncryptBase::setCheckRandNumber(QMap<int,char>& mapCheckRandNumber)
{
    QMap<int,char>::iterator iterMap;
    iterMap=mapCheckRandNumber.begin();
    while(iterMap!=mapCheckRandNumber.end())
    {
        this->mapCheckRandNumber.insert(iterMap.key(),iterMap.value());
        iterMap++;
    }
    return 0;
}

int ModeEncryptBase::setCheckCharacterAHQLM(QMap<char,int>& mapCheckCharacterAHQLM)
{
    QMap<char,int>::iterator iterMap;
    iterMap=mapCheckCharacterAHQLM.begin();
    while(iterMap!=mapCheckCharacterAHQLM.end())
    {
        this->mapCheckCharacterAHQLM.insert(iterMap.key(),iterMap.value());
        iterMap++;
    }
    return 0;
}
